Skip to content

[pull] main from expo:main#887

Merged
pull[bot] merged 28 commits into
code:mainfrom
expo:main
May 21, 2026
Merged

[pull] main from expo:main#887
pull[bot] merged 28 commits into
code:mainfrom
expo:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 21, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

kitten and others added 28 commits May 21, 2026 11:02
expo-router@56.2.4
expo-module-template@56.0.9
expo-template-tabs@56.0.16
expo-template-default@56.0.16
expo-template-blank-typescript@56.0.16
expo-template-blank@56.0.16
expo-template-bare-minimum@56.0.16
@expo/cli@56.1.9
expo@56.0.2
expo-observe@56.0.13
expo-image-manipulator@56.0.12
expo-image@56.0.7
expo-camera@56.0.6
…46079)

## Why

Previously `BareExpo's` `node_modules` folder was used as the source of
truth for selecting which 3rd party versions to pick. This failed when
we forgot to update BareExpo's package.json after updating
`bundlednativeVersions.json`.

## How

Now package resolving is done against the pnpm store instead of
BareExpo.

## Test-plan

✅ Ran `et prebuild -f Debug react-native-safe-area-context` when
RNCSafeAreaContext was set to 5.6.2 in BareEXpo and 5.7.0 in
bundledNativeVersions.json - built 5.7.0 correctly.
…t exist (#45973)

# Why
The cli commands that output multiple files take the `-o` option for
output directory. If it doesn't exist it just prints error and returns.
Now it will create the directories instead to make it easier to work
with.


<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->

# How

Run `fs.promises.mkdir(outDir, {recursive: true})` in the commands that
output files to a directory.
<!--
How did you build this feature or fix this bug and why?
-->

# Test Plan
Checked the cli commands manually.


<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
…#46077)

# Why

Fixes - #46060 and
#38323


<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->

# How
### 1. Crash fix 

Only set `svg.documentSize = size.toFloat()` if user passed width/height
is `> 0`. The root cause of crash was that the size of
documentHeight/Width was getting set to minimum integer value passed as
default by Glide (Glide passes this value as an indicator of no explicit
size passed)
<img width="200" height="auto" alt="Screenshot 2026-05-21 at 1 28 34 PM"
src="https://github.com/user-attachments/assets/8564efbc-999f-4093-9782-f0f302a4b69f"
/>

### 2. Fix SVG marker rendering in Expo Maps.

Call `toBitmap()` instead of `.bitmap`. `toBitmap()` calls the SVG
drawable's `toBitmap()` which rasterizes the vector to bitmap.


<!--
How did you build this feature or fix this bug and why?
-->

# Test Plan

- Added `useImage` with SVG testcase in bare-expo
- Added a screen for SVG maxWidth/height sizing to make sure output is
consistent on Android and iOS.

<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
# Why

Fix #46082

# How

Some packages doesn't have a package.json exports map, so for them we
used an `index.js` bridge file that re-export what' inside `/build`.
Those cannot be ES modules.

# Test Plan

- Clone https://github.com/LeonDvlpmnt/typed-config-plugins-reproducer
- Edit `node_modules/expo-camera/plugin/index.js` and add
`node_modules/expo-camera/plugin/index.d.ts`
- Restart the TS language server
- Run `expo start`, `expo prebuild`

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
# Why

Fix #45733 changelog entry being
incorrectly formatted.

# How

<!--
How did you build this feature or fix this bug and why?
-->

# Test Plan

<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
## Why

Fixes #40184. `expo-router/testing-library` imported Jest's private
`expect/build/matchers` module, which is gone in Jest 30 and causes the
testing-library helper to fail at import time.

## How

- Replace the private matcher import with Jest matcher context APIs:
`this.equals`, `this.utils.matcherHint`, and
`this.utils.printDiffOrStringify`.
- Apply the same matcher-context approach to `@expo/prebuild-config`'s
test-only matcher helpers.
- Remove the obsolete dependency-checker exception for
`expect/build/matchers`.
- Keep generated `expo-router/build/testing-library/expect.*` in sync
with the source change.

## Test Plan

- `pnpm --filter expo-router test --
src/__tests__/testing-library.test.ios.tsx --runInBand`
- `pnpm --filter @expo/prebuild-config test --
src/plugins/__tests__/withDefaultPlugins-test.ts
src/testing-library/__tests__/prebuild-testing-lib.test.ts --runInBand`
- `pnpm --filter @expo/prebuild-config test --
src/testing-library/__tests__/prebuild-testing-lib.test.ts --runInBand`
- `pnpm --filter @expo/prebuild-config test --
src/plugins/__tests__/withDefaultPlugins-test.ts --runInBand`
- `pnpm --filter @expo/prebuild-config test -- --watch false
--passWithNoTests --maxWorkers 1`
- `pnpm --filter expo-router exec eslint --max-warnings 0
src/testing-library/expect.ts
src/__tests__/testing-library.test.ios.tsx`
- `pnpm --filter @expo/prebuild-config exec eslint --max-warnings 0
src/testing-library/__tests__/expect.ts
src/testing-library/__tests__/prebuild-testing-lib.test.ts
src/plugins/__tests__/withDefaultPlugins-test.ts
src/testing-library/__tests__/prebuild-tester.ts`
- `git diff --check`
- `git diff --check upstream/main`

`pnpm --filter expo-router build` still fails after generation with the
existing `TS5095` module-resolution config error, so unrelated generated
build churn was restored and only `build/testing-library/expect.*` was
kept.

## Risk

Scope is limited to Jest matcher helper output in `expo-router`,
equivalent test-only helpers in `@expo/prebuild-config`, changelog
entries, and the dependency-checker exception removal. The generated
output is limited to the committed
`expo-router/build/testing-library/expect.*` files.

---------

Co-authored-by: Jakub Tkacz <jtkacz@expo.io>
## Why

After starting to use the right version of RNSkia through #46079 we had
a few build errors due to changes in RNSkia itself.

Merge after #46079

## How

This fixes the spm config and patches skia for prebuild.

## Test-plan

✅ Ran et prebuild @shopify/react-native-skia

# Checklist

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [x] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).

---------

Co-authored-by: Expo Bot <34669131+expo-bot@users.noreply.github.com>
#46100)

# Why

`CI=1 pnpm test` in `packages/@expo/prebuild-config` fails with `ENOENT:
... expo-updates/package.json` in `withDefaultPlugins-test.ts` and
`prebuild-testing-lib.test.ts`.

#45990 swapped `resolve-from` for `@expo/require-utils.resolveFrom` in
`@expo/config-plugins`, but the existing setup in `prebuild-config` only
had a manual mock for `resolve-from`. The new `resolveFrom` falls back
to Node's native `Module._resolveFilename`, so it resolves
`expo-updates/package.json` to the real on-disk path under
`packages/expo-updates/`. `getExpoUpdatesPackageVersion` then calls
`fs.readFileSync`, which doesn't have that path.

# How

Mirror the old `__mocks__/resolve-from.ts` for the new module: add
`packages/@expo/prebuild-config/__mocks__/@expo/require-utils.ts` that
walks `node_modules` via the mocked `fs` (memfs), so resolution stays
inside the virtual test filesystem. All other exports pass through
`jest.requireActual`.

# Test Plan

1. `CI=1 pnpm test` in `packages/@expo/prebuild-config` — 12 suites / 69
tests pass.
2. CI

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
#46092)

## Summary

Resolves #46078

There's two problems with how Fingerprint traces config plugins:
- it records them as `file`, but has no semantics for paths that may not
exist, and instead hard-crashes, which seems overly strict for some
cases where we're unsure about the path
- it reads paths from `module._cache`, ignores `filename` and uses the
IDs. Neither `module._cache` nor its keys are a representative list of
real filenames in some cases

For `module._cache`, while it's likely better to add a resolution hook
in the future, or something similar, to move away from `module._cache`,
for now, we can selectively filter out IDs that are unlikely to be
filenames. This then supports `evalModule` from `@expo/require-utils`
(and similar modules like `tsx` or `require-from-string`, if any
introduce filename remapping)

Further, we should define a new source type that allows for optional
file existence. This was added in this PR as `type: 'module'`, parallel
to `type: 'file'`, which only differs in the semantics that it's allowed
to bail on `ENOENT`.

> [!NOTE]
> This essentially fixes the source bug in two ways. Comment out the
`module._cache` fix to test the latter

## Set of changes

- Remap `module._cache[id]` to its `filename`, if it's set
- Filter out virtual modules by checking `filename === id`
- Add new `type: 'module'` to allow for optional files

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)

---------

Co-authored-by: Kudo Chien <kudo@expo.dev>
expo-web-browser@56.0.5
expo-video@56.1.2
expo-widgets@56.0.12
expo-updates@56.0.15
expo-type-information@0.0.5
expo-tracking-transparency@56.0.5
expo-task-manager@56.0.12
expo-system-ui@56.0.5
@expo/ui@56.0.11
expo-sqlite@56.0.4
expo-sharing@56.0.12
expo-sensors@56.0.5
expo-secure-store@56.0.4
expo-screen-orientation@56.0.5
expo-router@56.2.5
expo-notifications@56.0.12
expo-modules-autolinking@56.0.11
expo-maps@56.0.6
expo-media-library@56.0.6
expo-location@56.0.12
expo-mail-composer@56.0.4
expo-localization@56.0.6
expo-local-authentication@56.0.4
expo-image-picker@56.0.12
expo-image@56.0.8
expo-document-picker@56.0.4
expo-dev-menu@56.0.13
expo-dev-launcher@56.0.14
expo-dev-client@56.0.14
expo-contacts@56.0.7
expo-cellular@56.0.5
expo-calendar@56.0.8
expo-camera@56.0.7
expo-brightness@56.0.5
expo-background-fetch@56.0.12
expo-background-task@56.0.12
expo-audio@56.0.9
expo@56.0.3
expo-apple-authentication@56.0.4
@expo/prebuild-config@56.0.12
@expo/fingerprint@0.19.1
expo-template-tabs@56.0.17
expo-template-default@56.0.17
expo-template-blank-typescript@56.0.17
expo-template-blank@56.0.17
expo-template-bare-minimum@56.0.17
expo-constants@56.0.14
@expo/cli@56.1.10
expo-asset@56.0.13
@expo/metro-runtime@56.0.11
expo-app-metrics@56.0.12
expo-build-properties@56.0.13
expo-auth-session@56.0.11
patch-project@56.0.14
expo-processing@56.0.12
expo-observe@56.0.14
expo-image-manipulator@56.0.13
expo-insights@56.0.12
expo-brownfield@56.0.13
patch-project@56.0.14
expo-widgets@56.0.12
expo-web-browser@56.0.5
expo-video@56.1.2
expo-updates@56.0.15
@expo/ui@56.0.11
expo-type-information@0.0.5
expo-task-manager@56.0.12
expo-tracking-transparency@56.0.5
expo-system-ui@56.0.5
expo-sqlite@56.0.4
expo-sharing@56.0.12
expo-screen-orientation@56.0.5
expo-secure-store@56.0.4
expo-sensors@56.0.5
expo-router@56.2.5
expo-processing@56.0.12
expo-observe@56.0.14
expo-modules-test-core@56.0.5
expo-notifications@56.0.12
expo-modules-core@56.0.12
expo-modules-autolinking@56.0.11
expo-maps@56.0.6
expo-module-template@56.0.10
expo-location@56.0.12
expo-mail-composer@56.0.4
expo-localization@56.0.6
expo-local-authentication@56.0.4
expo-media-library@56.0.6
expo-linking@56.0.11
expo-insights@56.0.12
expo-image-picker@56.0.12
expo-image-manipulator@56.0.13
expo-image@56.0.8
expo-document-picker@56.0.4
expo-dev-menu@56.0.13
expo-dev-launcher@56.0.14
expo-contacts@56.0.7
expo-constants@56.0.14
expo-dev-client@56.0.14
expo-camera@56.0.7
expo-calendar@56.0.8
expo-brownfield@56.0.13
expo-brightness@56.0.5
expo-build-properties@56.0.13
expo-cellular@56.0.5
expo-background-task@56.0.12
expo-auth-session@56.0.11
expo-audio@56.0.9
expo-background-fetch@56.0.12
expo-asset@56.0.13
expo-apple-authentication@56.0.4
expo-app-metrics@56.0.12
expo@56.0.3
babel-preset-expo@56.0.11
@expo/router-server@56.0.11
@expo/prebuild-config@56.0.12
@expo/metro-runtime@56.0.11
@expo/fingerprint@0.19.1
@expo/cli@56.1.10
expo-template-tabs@56.0.17
expo-template-blank-typescript@56.0.17
expo-template-blank@56.0.17
expo-template-default@56.0.17
expo-template-bare-minimum@56.0.17
…ot provided (#46101)

## Why

`List(selection:)` opts into SwiftUI's selection-aware list rendering,
which changes row behavior (e.g. edit-mode chevrons, tap handling) even
when no selection is provided.

## How

Branch on `props.selection != nil` in `ListView.body`. When a
`selection` prop is provided, use the existing `List(selection:)` path
with the selection sync modifiers. Otherwise, fall back to the plain
`List { … }` initializer with no selection wiring.

## Test Plan

- Render `<List>` without a `selection` prop and confirm rows behave as
plain rows (no selection chrome).
- Render `<List selection={…} onSelectionChange={…}>` and confirm
selection still works (initial value, prop updates, and
`onSelectionChange` callback).
@pull pull Bot locked and limited conversation to collaborators May 21, 2026
@pull pull Bot added the ⤵️ pull label May 21, 2026
@pull pull Bot merged commit 5e52e0f into code:main May 21, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.